﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Resources;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Threading;
using Microsoft.Win32;

namespace SPResourceTranslator
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        private Cursor m_cursor;


        public Window1()
        {
            try
            {
                InitializeComponent();
                drpLanguage.ItemsSource = EnumToList<Translate.LangPair>();
                drpLanguage.SelectedIndex = 6;
                drpLocaleID.ItemsSource = CultureInfo.GetCultures(CultureTypes.FrameworkCultures).OrderBy(item => item.Name);
            }
            catch (Exception ex) {
                DisplayErrorBox(ex);
            }
        }

        private static MessageBoxResult DisplayErrorBox(Exception ex)
        {
            return MessageBox.Show(ex.Message, "Error:", MessageBoxButton.OK, MessageBoxImage.Error);
        }

        protected void ButtonBrowseResource_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                txtResourceLocation.Text = OpenFileDialog("Resource (*.resx)|*.resx");
                FileInfo file = new FileInfo(txtResourceLocation.Text);
                string[] tmp = file.Name.Split('.');
                bool containlocal = (tmp.Length == 3);
                if (containlocal)
                {
                    string loc = txtResourceLocation.Text.Replace(".resx", string.Empty).Replace(tmp[1], string.Empty);
                    txtSaveLocation.Text = loc.Remove(loc.Length - 1, 1);
                }
                else
                {
                    txtSaveLocation.Text = txtResourceLocation.Text.Replace(".resx", string.Empty);
                }
                Progressbar.Value = 0;
            }
            catch (Exception ex) {
                DisplayErrorBox(ex);
            }
        }

        protected void ButtonTranslate_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { StatusText.SetValue(TextBlock.TextProperty, "Initializing, please wait..."); }, null);
                m_cursor = this.Cursor;
                Cursor = Cursors.Wait;
                Stopwatch watch = new Stopwatch();
                watch.Start();
                if (txtResourceLocation.Text != string.Empty)
                {
                    FileInfo file = new FileInfo(txtResourceLocation.Text);
                    string saveloc = txtSaveLocation.Text + "." + drpLocaleID.SelectedItem.ToString() + ".resx";
                    FileInfo filetocreate = new FileInfo(saveloc);
                    if (filetocreate.Exists)
                    {
                        StatusText.Text = filetocreate.Name + " already exists!";
                    }
                    if (file.Exists)
                    {
                        Translate.LangPair langpair = (Translate.LangPair)Enum.Parse(typeof(Translate.LangPair), drpLanguage.SelectedItem.ToString());
                        ResXResourceReader reader = new ResXResourceReader(txtResourceLocation.Text);
                        ResXResourceWriter writer = new ResXResourceWriter(filetocreate.FullName);
                        int max = reader.Cast<DictionaryEntry>().Count();
                        Progressbar.Maximum = max;
                        Progressbar.Minimum = 0;

                        List<DictionaryEntry> translated = new List<DictionaryEntry>();

                        for (int i = 0; i < max; i++)
                        {
                            DictionaryEntry resxitem = (DictionaryEntry)reader.Cast<DictionaryEntry>().ToList()[i];
                            string key = resxitem.Key.ToString();
                            string value = resxitem.Value.ToString().GoolgeTranslate(langpair);
                            double progress = i + 1;
                            translated.Add(new DictionaryEntry(key, value));
                            string displayttext = "translating " + resxitem.Value.ToString() + " ...";
                            UpdateProgressBar(progress, displayttext);
                        }

                        foreach (DictionaryEntry trans in translated)
                        {
                            writer.AddResource(trans.Key.ToString(), trans.Value.ToString());
                        }


                        writer.Generate();
                        reader.Close();
                        writer.Close();
                        watch.Stop();
                        string text = translated.Count + " words translated in " + watch.Elapsed.Hours + ":" + watch.Elapsed.Minutes + ":" + watch.Elapsed.Seconds;
                        Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { StatusText.SetValue(TextBlock.TextProperty, text); }, null);
                        Cursor = m_cursor;
                    }
                    else
                    {
                        StatusText.Text = "The specified resource file does not exist!";
                    }
                }
                else
                {
                    StatusText.Text = "Select a valid resource file!";

                }
            }
            catch (Exception ex) {
                DisplayErrorBox(ex);
            }
        }

        public static List<T> EnumToList<T>()
        {
            Type enumType = typeof(T);

            // Can't use type constraints on value types, so have to do check like this
            if (enumType.BaseType != typeof(Enum))
                throw new ArgumentException("T must be of type System.Enum");

            Array enumValArray = Enum.GetValues(enumType);

            List<T> enumValList = new List<T>(enumValArray.Length);

            foreach (int val in enumValArray)
            {
                enumValList.Add((T)Enum.Parse(enumType, val.ToString()));
            }

            return enumValList;
        }
        private string OpenFileDialog(string filter)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Filter = filter;
            if (dialog.ShowDialog() == true)
            {
                return dialog.FileName;
            }
            return string.Empty;
        }
        private void UpdateProgressBar(double progress, string label)
        {
            string step = label;
            DispatcherFrame f = new DispatcherFrame();
            Dispatcher.CurrentDispatcher.BeginInvoke(
                DispatcherPriority.Background,
                (SendOrPostCallback)delegate(object arg)
                {
                    DispatcherFrame fr = arg as DispatcherFrame;
                    fr.Continue = false;
                },
                f
            );
            Dispatcher.PushFrame(f);
            Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { Progressbar.SetValue(ProgressBar.ValueProperty, progress); }, null);
            Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { StatusText.SetValue(TextBlock.TextProperty, step); }, null);
        }

        private void drpLanguage_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                Translate.LangPair langpair = (Translate.LangPair)Enum.Parse(typeof(Translate.LangPair), drpLanguage.SelectedItem.ToString());
                CultureInfo ci = Translate.GetCultureInfo(langpair);
                drpLocaleID.SelectedItem = ci;
            }
            catch (Exception ex)
            {
                drpLocaleID.SelectedIndex = -1;
            }
        }

    }
}
